package pe.com.bbva.ge.vista.vaadin.ui;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;

import pe.com.bbva.ge.domain.seguridad.Opcion;
import pe.com.bbva.ge.domain.seguridad.Permiso;
import pe.com.bbva.ge.domain.seguridad.Rol;
import pe.com.bbva.ge.negocio.ConfiguracionNegocio;
import pe.com.bbva.ge.utileria.Constante;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Item;
import com.vaadin.data.Property.ValueChangeEvent;
import com.vaadin.data.Property.ValueChangeListener;
import com.vaadin.data.util.IndexedContainer;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.CheckBox;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Table;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.VerticalLayout;

public class PermisosUI extends VentanaUI implements ClickListener {

	@AutoGenerated
	private VerticalLayout mainLayout;
	@AutoGenerated
	private Button btnGrabar;
	@AutoGenerated
	private HorizontalLayout pnlListaContenido;
	@AutoGenerated
	private VerticalLayout pnlOpciones;
	@AutoGenerated
	private TreeTable treeOpciones;
	@AutoGenerated
	private Label lblOpciones;
	@AutoGenerated
	private VerticalLayout pnlRoles;
	@AutoGenerated
	private Table tblRoles;
	@AutoGenerated
	private Label lblRoles;
	
	Map<String, List<Opcion>> map;

	@Autowired
	private ConfiguracionNegocio genericoNegocio;

	public PermisosUI() {
		buildMainLayout();
		setCompositionRoot(mainLayout);
		debugId();
	}
	
	private void debugId(){
		mainLayout.setDebugId("mainLayout");
		btnGrabar.setDebugId("btnGrabar");
		pnlListaContenido.setDebugId("pnlListaContenido");
		pnlOpciones.setDebugId("pnlOpciones");
		treeOpciones.setDebugId("treeOpciones");
		lblOpciones.setDebugId("lblOpciones");
		pnlRoles.setDebugId("pnlRoles");
		tblRoles.setDebugId("tblRoles");
		lblRoles.setDebugId("lblRoles");
	}
	
	public void postConstruccion() {
		
		List<Rol> roles = genericoNegocio.buscarRoles(null);
		cargarRoles(roles);
		
		tblRoles.setSelectable(true);
		tblRoles.setImmediate(true);
		tblRoles.setNullSelectionAllowed(true);
		tblRoles.setNullSelectionItemId(null);
		
		cargarOpciones();
		
		btnGrabar.setEnabled(false);
		
		tblRoles.addListener(new ValueChangeListener() {

			private static final long serialVersionUID = -5647168576288038657L;

			@Override
			public void valueChange(ValueChangeEvent event) {
				
				btnGrabar.setEnabled(false);
				
				List<Permiso> permisos = null;
				if(tblRoles.getValue() != null)
				{
					Long idRol = obtenerIdRolSeleccionado();
					permisos = genericoNegocio.obtenerPermisosXRol(idRol, true);
					btnGrabar.setEnabled(true);
				}
				
				limpiarOpciones();
				
				if(permisos != null)
				{
					for (Permiso permiso : permisos) {
						Item item = obtenerItemOpcion(permiso.getOpcion().getId());
						if(item != null)
						{
							setCheckBoxOpcion(item, true);
						}
					}
				}				
			}
			
		});
		
		btnGrabar.addListener((ClickListener)this);

	}	
	
	@Override
	public void buttonClick(ClickEvent event) {
		if(event.getButton().equals(btnGrabar))
		{
			buttonClickGrabar();
		}
		else //if(event.getSource() instanceof CheckBox)
		{
			System.out.println("====================================");
			System.out.println(event.getButton());
			System.out.println(event.getSource());
		}
	}
	
	@SuppressWarnings("rawtypes")
	private void buttonClickGrabar(){

		Long idRol = obtenerIdRolSeleccionado();
		List<Long> idsOpciones = new ArrayList<Long>();
		
		Collection lista = treeOpciones.getItemIds();
		for (Iterator i = lista.iterator(); i.hasNext(); )
		{
			Object valor = i.next();
			Item item = treeOpciones.getItem(valor);
			CheckBox chk = (CheckBox) item.getItemProperty("permiso").getValue();
			if(chk.booleanValue())
			{
				Long idOpcion = (Long) item.getItemProperty("id").getValue();
				idsOpciones.add(idOpcion);
			}
		}
		
		genericoNegocio.guardarPermisos(idRol, idsOpciones);
	
	}
	
	private Long obtenerIdRolSeleccionado()
	{
		Item item = tblRoles.getItem(tblRoles.getValue());
		return (Long) item.getItemProperty("id").getValue();
	}
	
	@SuppressWarnings("rawtypes")
	private void limpiarOpciones() {
		Collection lista = treeOpciones.getItemIds();
		for (Iterator i = lista.iterator(); i.hasNext(); )
		{
			Object valor = i.next();
			Item item = treeOpciones.getItem(valor);
			setCheckBoxOpcion(item, false);
		}
	}
	
	private void setCheckBoxOpcion(Item item, boolean flag)
	{
		CheckBox chk = (CheckBox) item.getItemProperty("permiso").getValue();
		chk.setValue(flag);
	}
	
	@SuppressWarnings("rawtypes")
	private Item obtenerItemOpcion(Long idOpcion)
	{
		Collection lista = treeOpciones.getItemIds();
		for (Iterator i = lista.iterator(); i.hasNext(); )
		{
			Object valor = i.next();
			Item item = treeOpciones.getItem(valor);
			Long opcion = (Long) item.getItemProperty("id").getValue();
			if(idOpcion.longValue() == opcion.longValue())
			{
				return item;
			}
		}
		return null;
	}
	
	private void cargarOpciones() {
		
//		Map<String, List<Opcion>> 
		map = genericoNegocio.listarOpciones();
		
		CheckBox chk = new CheckBox();
		chk.addListener(this);
		
		treeOpciones.addContainerProperty("permiso", CheckBox.class, chk);
		treeOpciones.addContainerProperty("tipo", String.class, "");
		treeOpciones.addContainerProperty("id", Long.class, 0L);
		treeOpciones.setImmediate(true);
		
		recorrer(Constante.OPCION.KEY_PADRE, map, null);
		
		treeOpciones.setVisibleColumns(new Object[]{"permiso", "tipo"});
	}
	
	public void seleccionarHijos(Object opcion,boolean valor){		
		Collection lstHijos=treeOpciones.getChildren(opcion);
		if(lstHijos==null)return;
		for (Object hijo : lstHijos) {
			Item item = treeOpciones.getItem(hijo);
			if(item != null)
			{
				setCheckBoxOpcion(item, valor);
				seleccionarHijos(hijo, valor);
			}
		}
	}
	
	public void deseleccionarPadre(Object opcion,boolean valor){
		int seleccionados=0;
		Object parent=treeOpciones.getParent(opcion);
		Collection lstHijos=treeOpciones.getChildren(parent);
		if(lstHijos==null)return;
		for (Object hijo : lstHijos) {
			Item item = treeOpciones.getItem(hijo);
			if(item != null)
			{
				CheckBox chk = (CheckBox) item.getItemProperty("permiso").getValue();
				if(chk.booleanValue()){
					seleccionados++;
				}
			}
		}
		System.out.println("seleccionados: "+seleccionados);
		if(seleccionados==0){setCheckBoxOpcion(treeOpciones.getItem(parent), false);
		}else{setCheckBoxOpcion(treeOpciones.getItem(parent), true);}
		deseleccionarPadre(parent,false);
	}	
	
	private void recorrer(String codigo, Map<String, List<Opcion>> map, Object objPadre) {
		for (Opcion opc : map.get(codigo)) {
			
			CheckBox chk = new CheckBox(opc.getNombre());
			//chk.setData(opc.getId());
			chk.setImmediate(true);
			chk.addListener(new ClickListener() {

				private static final long serialVersionUID = -2056672559324022605L;

				@Override
				public void buttonClick(ClickEvent event) {
					System.out.println("====================================");
					System.out.println(event.getButton());
					System.out.println(event.getSource());
					CheckBox chkAux=(CheckBox)event.getSource();
					boolean valor=Boolean.parseBoolean(event.getSource().toString());
					Object opcion = chkAux.getData();
					seleccionarHijos(opcion,valor);
//					if(!valor){
						deseleccionarPadre(opcion,false);
//					}
				}
			});
			
			Object opcion = treeOpciones.addItem(new Object[] { chk,
					opc.getTipo().getNombre(), opc.getId()}, null);
			chk.setData(opcion);
			//treeOpciones.get
			
			if (!codigo.equals(Constante.OPCION.KEY_PADRE)) {
				treeOpciones.setParent(opcion, objPadre);
			}

			if (map.get(opc.getCodigo()) != null) {
				treeOpciones.setCollapsed(opcion, false);
				recorrer(opc.getCodigo(), map, opcion);
			} else {
				treeOpciones.setChildrenAllowed(opcion, false);
			}
		}
	}

	private void cargarRoles(List<Rol> roles)
	{
		IndexedContainer container = new IndexedContainer();
		
		container.addContainerProperty("id", Long.class,  null);
		container.addContainerProperty("codigo", String.class,  null);
		container.addContainerProperty("nombre", String.class, null);
		container.addContainerProperty("descripcion", String.class, null);
		
		int con=1;
		for (Rol rol : roles) {
			Item item = container.addItem(con++);
			item.getItemProperty("id").setValue(rol.getId());
            item.getItemProperty("codigo").setValue(rol.getCodigo());
            item.getItemProperty("nombre").setValue(rol.getNombre());
            item.getItemProperty("descripcion").setValue(rol.getDescripcion());
		}
		
		tblRoles.setContainerDataSource(container);
		tblRoles.setVisibleColumns(new Object[]{"codigo", "nombre", "descripcion"});
		tblRoles.setColumnWidth("codigo", 90);
		tblRoles.setColumnWidth("nombre", 150);
		tblRoles.setColumnWidth("descripcion", 180);
		tblRoles.setColumnHeader("codigo", "Código");
		tblRoles.setColumnHeader("nombre", "Nombre");
		tblRoles.setColumnHeader("descripcion", "Descripción");		
	}

	@AutoGenerated
	private VerticalLayout buildMainLayout() {
		// common part: create layout
		mainLayout = new VerticalLayout();
		mainLayout.setImmediate(false);
		mainLayout.setWidth("100%");
		mainLayout.setHeight("100%");
		mainLayout.setMargin(false);
		
		// top-level component properties
		setWidth("100.0%");
		setHeight("100.0%");
		
		// pnlListaContenido
		pnlListaContenido = buildPnlListaContenido();
		mainLayout.addComponent(pnlListaContenido);
		
		// btnGrabar
		btnGrabar = new Button();
		btnGrabar.setCaption("Grabar");
		btnGrabar.setImmediate(true);
		btnGrabar.setWidth("-1px");
		btnGrabar.setHeight("-1px");
		mainLayout.addComponent(btnGrabar);
		
		return mainLayout;
	}

	@AutoGenerated
	private HorizontalLayout buildPnlListaContenido() {
		// common part: create layout
		pnlListaContenido = new HorizontalLayout();
		pnlListaContenido.setImmediate(false);
		pnlListaContenido.setWidth("1000px");
		pnlListaContenido.setHeight("-1px");
		pnlListaContenido.setMargin(true);
		
		// pnlRoles
		pnlRoles = buildPnlRoles();
		pnlListaContenido.addComponent(pnlRoles);
		
		// pnlOpciones
		pnlOpciones = buildPnlOpciones();
		pnlListaContenido.addComponent(pnlOpciones);
		
		return pnlListaContenido;
	}

	@AutoGenerated
	private VerticalLayout buildPnlRoles() {
		// common part: create layout
		pnlRoles = new VerticalLayout();
		pnlRoles.setImmediate(false);
		pnlRoles.setWidth("500px");
		pnlRoles.setHeight("-1px");
		pnlRoles.setMargin(false);
		pnlRoles.setSpacing(true);
		
		// lblRoles
		lblRoles = new Label();
		lblRoles.setImmediate(false);
		lblRoles.setWidth("-1px");
		lblRoles.setHeight("-1px");
		lblRoles.setValue("Roles");
		pnlRoles.addComponent(lblRoles);
		
		// tblRoles
		tblRoles = new Table();
		tblRoles.setImmediate(false);
		tblRoles.setWidth("400px");
		tblRoles.setHeight("400px");
		pnlRoles.addComponent(tblRoles);
		
		return pnlRoles;
	}

	@AutoGenerated
	private VerticalLayout buildPnlOpciones() {
		// common part: create layout
		pnlOpciones = new VerticalLayout();
		pnlOpciones.setImmediate(false);
		pnlOpciones.setWidth("500px");
		pnlOpciones.setHeight("-1px");
		pnlOpciones.setMargin(false);
		pnlOpciones.setSpacing(true);
		
		// lblOpciones
		lblOpciones = new Label();
		lblOpciones.setImmediate(false);
		lblOpciones.setWidth("-1px");
		lblOpciones.setHeight("-1px");
		lblOpciones.setValue("Opciones");
		pnlOpciones.addComponent(lblOpciones);
		
		// treeOpciones
		treeOpciones = new TreeTable();
		treeOpciones.setImmediate(false);
		treeOpciones.setWidth("400px");
		treeOpciones.setHeight("400px");
		pnlOpciones.addComponent(treeOpciones);
		
		return pnlOpciones;
	}
}
